package com.cn.util;

import com.alibaba.fastjson.JSON;
import com.cn.ConstantNacosUtil;
import com.cn.menu.ButtonsDO;
import com.cn.msg.ResultMsg;
import com.cn.redis.RedisHandleUtil;
import com.cn.web.menu.vo.MenuVO;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * description: 获取到其他系统后的应用菜单统一处理工具 <br>
 * date: 23.5.31 11:44 <br>
 * author: cn_yaojin <br>
 * version: 1.0 <br>
 */
public final class AppMenuUtil {

    private static final String APP_MENU_CACHE = ConstantNacosUtil.PROGRAM_NAME + ":APPMENUS:MAP";

    public final static String parentId = "0";

    /**
     * 将第三方应用的菜单加入的缓存中
     *
     * @param list
     * @param appId
     */
    public static void addCache(List<MenuVO> list, String appId) {
        RedisHandleUtil.addMap(APP_MENU_CACHE, appId, JSON.toJSONString(list));
    }

    /**
     * 查询第三方应的菜单集合
     *
     * @param appId
     * @return
     */
    public static List<MenuVO> getCache(String appId) {
        Object value = RedisHandleUtil.getMap(APP_MENU_CACHE, appId);
        if (value != null) {
            return JSON.parseArray(value.toString(), MenuVO.class);
        }
        return new ArrayList<>();
    }

    /**
     * 移除第三方应用的菜单集合
     *
     * @param appId
     */
    public static void delCache(String appId) {
        RedisHandleUtil.delMap(APP_MENU_CACHE, appId);
    }


    /**
     * 解析原始菜单
     * 在跟第三方对接的时候，必须要求第三方按照中台的要求提供数据，否则会解析错误
     *
     * @param json
     * @param appId
     */
    public static List<MenuVO> formatMenu(String json, String appId) {
        var result = JsonUtil.parseObject(json, AppMenuTmpParseJsonResult.class);
        List<MenuVO> list = new ArrayList<>();
        if (result.getCode() == 200) {
            var tmp = result.getData().stream().filter(t -> t.getParentNo().equals(parentId)).collect(Collectors.toList());
            for (AppMenuTmpParseJson t : tmp) {
                MenuVO menuVO = new MenuVO();
                menuVO.setLevel(1).setMenuName(t.getMenuName()).setMenuNo(t.getMenuNo())
                        .setParentNo(t.getParentNo());
                packMenu2Tree(result.getData(), menuVO, 2);
                menuVO.getChild().addAll(packButton2Tree(t.getButtons(), menuVO));
                menuVO.setButtonArray(t.getButtons());
                list.add(menuVO);
            }
        }
        return list;
    }

    private static void packMenu2Tree(List<AppMenuTmpParseJson> sources, MenuVO menuVO, int level) {
        var tmp = sources.stream().filter(t -> t.getParentNo().equals(menuVO.getMenuNo())).collect(Collectors.toList());
        menuVO.setChild(new ArrayList<>());
        if (tmp != null && tmp.size() > 0) {
            for (AppMenuTmpParseJson t : tmp) {
                MenuVO tmpMenu = new MenuVO();
                tmpMenu.setLevel(level).setMenuName(t.getMenuName()).setMenuNo(t.getMenuNo())
                        .setParentNo(t.getParentNo());
                menuVO.getChild().add(tmpMenu);
                packMenu2Tree(sources, tmpMenu, level + 1);
                tmpMenu.getChild().addAll(packButton2Tree(t.getButtons(), tmpMenu));
                tmpMenu.setButtonArray(t.getButtons());
            }
        }
    }

    private static List<MenuVO> packButton2Tree(List<ButtonsDO> buttons, MenuVO menuVO) {
        List<MenuVO> list = new ArrayList<>();
        if (buttons != null && buttons.size() > 0) {
            for (int i = 0; i < buttons.size(); i++) {
                var button = buttons.get(i);
                MenuVO tmpMenu = new MenuVO();
                if (StringUtils.isEmpty(button.getNo())) {
                    button.setNo(i + "");
                }
                tmpMenu.setLevel(100).setMenuName(button.getName()).setMenuNo(menuVO.getMenuNo() + "_" + button.getNo()).setAppType(2);
                list.add(tmpMenu);
            }
        }
        return list;
    }

    @Setter
    @Getter
    @Accessors(chain = true)
    public static class AppMenuTmpParseJsonResult extends ResultMsg<List<AppMenuTmpParseJson>> {

    }

    @Setter
    @Getter
    @Accessors(chain = true)
    public static class AppMenuTmpParseJson {

        @ApiModelProperty(value = "菜单编号")
        private String menuNo;

        @ApiModelProperty(value = "菜单名称")
        private String menuName;

        @ApiModelProperty(value = "父级菜单编号，传给中台的顶级菜单的parentId必须为0")
        private String parentNo;

        @ApiModelProperty(value = "按钮集")
        private List<ButtonsDO> buttons;


    }


}
